package com.ete.service.util

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import com.blankj.utilcode.util.Utils
import com.ete.service.service.hardware.UploadHardwareUtil
import java.util.*

/**
 * 唯一ID工具获取类
 * @author chenxiaojin
 * @date 2024/1/12
 */
object DeviceUtils {

    @Volatile
    private var udid: String = ""

    private lateinit var sp: SharedPreferences

    private const val KEY_UDID = "KEY_UDID"

    private var mApp: Application? = null

    //设备型号
    const val ETE_HT930 = "HT930"
    const val ETE_HT950 = "HT950"
    const val ETE_HT960 = "HT960"

    /**
     * 初始化
     */
    @JvmStatic
    fun init(mApp: Application) {
        this.mApp = mApp
    }

    /**
     * 获取主机设备唯一ID
     */
    @JvmStatic
    fun getUniqueDeviceId(): String {
        return this.getUniqueDeviceId(getApplication())
    }

    /**
     * 获取AndroidID
     */
    @JvmStatic
    fun getAndroidID(): String {
        return getAndroidID(getApplication())
    }

    /**
     * 获取固件版本
     */
    @JvmStatic
    fun getFirmwareVersion(): String {
        return UploadHardwareUtil.getFirmwareVersion()
    }

    @JvmStatic
    private fun getApplication(): Application {
        if (Utils.getApp() == null && mApp == null) {
            throw ExceptionInInitializerError("平台服务未初始化")
        }
        return mApp ?: Utils.getApp()
    }

    /**
     * 初始化SP
     */
    private fun initSP(context: Context) {
        if (!::sp.isInitialized) {
            sp = context.getSharedPreferences("UniqueSP", android.content.Context.MODE_PRIVATE)
        }
    }

    /**
     * 获取系统属性值
     *
     * @param key 长度不能超过31，key.length <= 30
     * @param defValue
     * @return
     */
    @SuppressLint("PrivateApi")
    private operator fun get(key: String?, defValue: String?): String? {
        // android.os.SystemProperties
        // public static String get(String key, String def)
        try {
            val cls = Class.forName("android.os.SystemProperties")
            val method = cls.getMethod(
                    "get",
                    String::class.java,
                    String::class.java
            )
            return method.invoke(null, key, defValue) as String
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return defValue
    }

    private fun getUniqueDeviceId(context: Context): String {
        initSP(context)
        return getUniqueDeviceId(context, "", true)
    }

    private fun getUniqueDeviceId(context: Context, prefix: String?, useCache: Boolean): String {
        if (!useCache) {
            return getUniqueDeviceIdReal(context, prefix)
        }
        if (udid.isEmpty()) {
            synchronized(com.ete.service.util.DeviceUtils::class.java) {
                if (udid.isEmpty()) {
                    val id = sp.getString(KEY_UDID, null)
                    if (id != null) {
                        udid = id
                        return udid
                    }
                    return getUniqueDeviceIdReal(context, prefix)
                }
            }
        }
        return udid
    }

    @JvmStatic
    private fun getUniqueDeviceIdReal(context: Context, prefix: String?): String {
        try {
            val androidId = getAndroidID(context)
            if (!TextUtils.isEmpty(androidId)) {
                return saveUdid(prefix + 2, androidId)
            }
        } catch (ignore: java.lang.Exception) { /**/
        }
        return saveUdid(prefix + 9, "")
    }

    @SuppressLint("HardwareIds")
    @JvmStatic
    private fun getAndroidID(context: Context): String {
        val id = Settings.Secure.getString(
                context.contentResolver,
                Settings.Secure.ANDROID_ID
        )
        return if ("9774d56d682e549c" == id) "" else id ?: ""
    }

    private fun saveUdid(prefix: String, id: String): String {
        udid = getUdid(prefix, id)
        sp.edit().putString(KEY_UDID, udid).apply()
        return udid
    }

    private fun getUdid(prefix: String, id: String): String {
        return if (id == "") {
            prefix + UUID.randomUUID().toString().replace("-", "")
        } else prefix + UUID.nameUUIDFromBytes(id.toByteArray()).toString().replace("-", "")
    }

    @JvmStatic
    val isHT930: Boolean by lazy { Build.MODEL.uppercase().contains(ETE_HT930) }

    @JvmStatic
    val isHT960: Boolean by lazy { Build.MODEL.uppercase().contains(ETE_HT960) }
}